#include <stdio.h>
#include <string.h>

#include    "gameapp.h"

#include    "personal/common.h"
#include    "personal/audio/audio_engine.h"



#include    "personal/scene/splashscene.h"
#include    "personal/scene/menuscene.h"
#include    "personal/scene/creditsscene.h"
#include    "personal/scene/runningscene.h"
#include    "personal/scene/pausedscene.h"




#define GAME_FPS     60

GameApp::GameApp():
    m_texts
    {
        "splash",
        "loadding",
        "menu",
        "running",
        "paused",
        "credits",
        "nextlevel",
        "over"
    },
    m_loadFunctions
    {
        &GameApp::loadScene_splash,
        &GameApp::loadScene_loadding,
        &GameApp::loadScene_menu,
        &GameApp::loadScene_running,
        &GameApp::loadScene_paused,
        &GameApp::loadScene_credits,
        &GameApp::loadScene_nextlevel,
        &GameApp::loadScene_over,
    }
{
    memset(m_scenes,0,sizeof(m_scenes));
    m_previousTime = GetTickCount();//glutGet(GLUT_ELAPSED_TIME);
    m_fontManager = 0;
    m_run = false;

    initSomething();

    setGameState(GAMESTATE_SPLASH);
}

GameApp::~GameApp()
{
    for(int i = 0 ; i < GAMESTATE_OVER + 1 ; i++)
    {
        if(m_scenes[i] == 0)
        {
            continue;
        }

        delete m_scenes[i];
        m_scenes[i] = 0;
    }

    releaseSomething();

    SAFE_DELETE_OBJ(m_fontManager);
}

void GameApp::initSomething()
{
    AudioEngine::createInstance();
    AudioEngine* audioEngin =  AudioEngine::getInstance();
    audioEngin->initAudioEngin();

    std::string jollybot = "jollybot";
    std::string button = "button";
    audioEngin->loadSound("resources/sounds/jollybot.mp3",jollybot);
    audioEngin->loadSound("resources/sounds/jump.wav",button);
}

void GameApp::releaseSomething()
{
    AudioEngine::releaseInstance();
}

void GameApp::loadScene_splash()
{
    if(m_scenes[GAMESTATE_SPLASH])
    {
        return;
    }

    m_scenes[GAMESTATE_SPLASH] = new SplashScene(this);
}

void GameApp::loadScene_loadding(){}

void GameApp::loadScene_menu()
{
    if(m_scenes[GAMESTATE_MENU])
    {
        return;
    }

    m_scenes[GAMESTATE_MENU] = new MenuScene(this);
}


void GameApp::loadScene_running()
{
    if(m_scenes[GAMESTATE_RUNNING])
    {
        return;
    }

    m_scenes[GAMESTATE_RUNNING] = new RunningScene(this);
}

void GameApp::loadScene_paused()
{
    if(m_scenes[GAMESTATE_PAUSED])
    {
        return;
    }

    m_scenes[GAMESTATE_PAUSED] = new PausedScene(this,m_scenes[GAMESTATE_RUNNING]);
}

void GameApp::loadScene_credits()
{
    if(m_scenes[GAMESTATE_CREDITS])
    {
        return;
    }

    m_scenes[GAMESTATE_CREDITS] = new CreditsScene(this);
}

void GameApp::loadScene_nextlevel(){}
void GameApp::loadScene_over(){}


void GameApp::render()
{
    if(m_scenes[m_state] == 0)
    {
        loadScene(m_state);
        return;
    }

    glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
//    printf("render:%s\n",m_texts[m_state]);
    m_scenes[m_state]->render();

    SwapBuffers(m_window.getHelpDC());
}

void GameApp::update(TimeSeconds detalTime)
{

    if(m_scenes[m_state] == 0)
    {
        loadScene(m_state);
        return;
    }

//    printf("update:%s\n",m_texts[m_state]);
    m_scenes[m_state]->update(detalTime);
}

void GameApp::loadScene(GameState state)
{
    if(m_scenes[state] != 0)
    {
        return;
    }
//   LoadSceneFunction func = m_loadFunctions[state];
//   (this->*func)();
    (this->*m_loadFunctions[state])();
    printf("load %s!\n",m_texts[state]);
}

void GameApp::setGameState(GameState state)
{
    if(state == m_state)
    {
        return ;
    }

    if(m_scenes[state] != 0)
    {
        m_scenes[state]->on();
    }

    m_state = state;
}


void GameApp::run()
{
    if(m_run){return;}

    m_run = true;
    if(m_window.getHelpHWND() == 0)
    {
        m_window.createGLWindow(0,"GameApp",400,100,800,600);
        m_fontManager = new FontManager();
        m_fontManager->buildFont(m_window.getHelpDC());
    }

    messageProcess();
}

void GameApp::exit()
{
    m_run = false;
}

void GameApp::messageProcess()
{
    MSG msg;
    while (m_run)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT)
            {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            int currentTime = GetTickCount();//glutGet(GLUT_ELAPSED_TIME);
            TimeSeconds deltaTime = (TimeSeconds)(currentTime - m_previousTime)/1000;

            if(deltaTime < 1.0/GAME_FPS)
            {
                continue;
            }

            m_previousTime = currentTime;


            update(deltaTime);
            render();
        }
    }
}
